package com.iot.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.iot.commons.ResponseResult;
import com.iot.enums.*;
import com.iot.mapper.MessageMapper;
import com.iot.mapper.ShareMapper;
import com.iot.mapper.UserInfoMapper;
import com.iot.model.dto.FollowDto;
import com.iot.model.dto.ShareMessageDto;
import com.iot.model.entity.MessageEntity;
import com.iot.model.entity.ShareEntity;
import com.iot.model.entity.UserInfoEntity;
import com.iot.model.query.ShareQuery;
import com.iot.model.dto.ShareDto;
import com.iot.model.vo.AuthInfoVo;
import com.iot.model.vo.BaseVo;
import com.iot.model.vo.ShareVo;
import com.iot.model.vo.UserInfoVo;
import com.iot.service.FollowService;
import com.iot.service.ShareService;
import com.iot.service.UserInfoService;
import com.iot.utils.AppPushUtils;
import com.iot.utils.DateUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.iot.utils.ResponseResultUtil;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * ShareServiceImpl
 *
 * @author: dh
 * @date: 2024-04-22 14:51:44
 */
@Service
@RequiredArgsConstructor
public class ShareServiceImpl implements ShareService {

    private final ShareMapper shareMapper;

    private final FollowService followService;

    private final MessageMapper messageMapper;

    private final UserInfoMapper userInfoMapper;

    private final UserInfoService userInfoService;

    @Override
    public ResponseResult getList(ShareQuery share) {
        Page<ShareEntity> page = new Page<>(share.getPageIndex(), share.getPageSize());
        LambdaQueryWrapper<ShareEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ShareEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.orderByDesc(ShareEntity::getCreateTime);
        IPage<ShareEntity> sharePage = shareMapper.selectPage(page, queryWrapper);
        List<ShareVo> shareVoList = Lists.newArrayList();
        for (ShareEntity shareEntity : sharePage.getRecords()) {
            ShareVo vo = new ShareVo();
            vo.setId(shareEntity.getId());
            vo.setLaunchAuthId(shareEntity.getLaunchAuthId());
            vo.setSharePhone(shareEntity.getPhone());
            vo.setShareAuthId(shareEntity.getUid());
            vo.setDataTypes(shareEntity.getDataTypes());
            vo.setIsRead(shareEntity.getIsRead());
            vo.setAccept(shareEntity.getAccept());
            vo.setType(shareEntity.getType());
            vo.setState(shareEntity.getState());
            vo.setCreateTime(shareEntity.getCreateTime());
            vo.setUpdateTime(shareEntity.getUpdateTime());
            shareVoList.add(vo);
        }

        return ResponseResultUtil.success(sharePage.getTotal(), shareVoList);
    }

    @Transactional
    @Override
    public ResponseResult reply(ShareDto share) {
        AuthInfoVo authInfoEntity = (AuthInfoVo) StpUtil.getSession().get("loginInfo");
        if (null == authInfoEntity) {
            return ResponseResultUtil.authInfoFailure();
        }
        if (null == share) {
            return ResponseResultUtil.paramFailure();
        }

        UserInfoVo loginUser = userInfoService.getByAuthId(authInfoEntity.getId());
        if (null == loginUser) {
            return ResponseResultUtil.failure();
        }

        Long uid = share.getUid();
        Integer accept = share.getAccept();
        if (null == uid || null == accept) {
            return ResponseResultUtil.paramFailure();
        }

        UserInfoEntity userInfoEntity = userInfoMapper.selectById(uid);
        if (null == userInfoEntity) {
            return ResponseResultUtil.failure("用户不存在", 11006);
        }

        LambdaQueryWrapper<ShareEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ShareEntity::getLaunchAuthId, userInfoEntity.getAuthId());
        queryWrapper.eq(ShareEntity::getUid, loginUser.getUid());
        queryWrapper.eq(null != share.getType(), ShareEntity::getType, share.getType());
        queryWrapper.eq(ShareEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.isNull(ShareEntity::getAccept);
        queryWrapper.last("limit 1");
        ShareEntity shareEntity = shareMapper.selectOne(queryWrapper);
        if (null == shareEntity) {
            return ResponseResultUtil.failure("消息已处理", 11011);
        }

        Long launchAuthId = shareEntity.getLaunchAuthId();
        String dataTypes = shareEntity.getDataTypes();
        Integer type = shareEntity.getType();
        /*if (type.equals(1) && accept.equals(0) && null == dataTypes) {
            return ResponseResultUtil.paramFailure();
        }*/
        ShareEntity entity = new ShareEntity();
        entity.setId(shareEntity.getId());
        entity.setIsRead(0);
        entity.setAccept(accept);
        entity.setUpdateTime(DateUtil.now());
        shareMapper.updateById(entity);

        Long id = null;
        if (accept.equals(0)) {
            FollowDto dto = new FollowDto();
            //邀请
            if (type.equals(0)) {
                dto.setDataTypes(shareEntity.getDataTypes());
                dto.setAuthId(launchAuthId);
                dto.setFollowAuthId(authInfoEntity.getId());
                if (check(launchAuthId, userInfoEntity.getAuthId(), type)) {
                    return ResponseResultUtil.failure("重复关注", 11003);
                }

            } else if (type.equals(1)) {
                dto.setDataTypes(dataTypes);
                dto.setAuthId(authInfoEntity.getId());
                dto.setFollowAuthId(launchAuthId);
                if (check(launchAuthId, userInfoEntity.getAuthId(), type)) {
                    return ResponseResultUtil.failure("重复关注", 11003);
                }
            }
            dto.setCreateTime(DateUtil.now());
            dto.setState(StatusEnum.VALID.getKey());
            id = followService.add(dto);
        }
        String nickName = "";

        nickName = StringUtils.isEmpty(loginUser.getNickName()) ? loginUser.getPhone() : loginUser.getNickName();

        Long messageId = share.getMessageId();
        if (null == messageId) {
            LambdaQueryWrapper<MessageEntity> messageWrapper = Wrappers.lambdaQuery();
            messageWrapper.eq(MessageEntity::getSid,shareEntity.getId());
            MessageEntity messageEntity = messageMapper.selectOne(messageWrapper);
            if (null != messageEntity) {
                messageId = messageEntity.getId();
            }
        }
        updateMessageStatus(messageId, accept.equals(0) ? 1 : 2);
        //（0-邀请，1-申请）  是否同意（0-同意，1-）
        String title = type.equals(0) ? "邀请关注" : "申请关注";
        //String content = nickName + (accept.equals(0) ? "同意了" : "拒绝了") + title;
        String content = "";
        if (type.equals(0)) {
            content = accept.equals(0) ? AcceptInviteContentEnum.getByCode(share.getLanguage()).replace(LanguageEnum.NICKNAME.getValue(), nickName) :
                    RejectInviteContentEnum.getByCode(share.getLanguage()).replace(LanguageEnum.NICKNAME.getValue(), nickName);
        } else {
            content = accept.equals(0) ? AcceptApplyContentEnum.getByCode(share.getLanguage()).replace(LanguageEnum.NICKNAME.getValue(), nickName) :
                    RejectApplyContentEnum.getByCode(share.getLanguage()).replace(LanguageEnum.NICKNAME.getValue(), nickName);
        }

        sendMessage(title, content, null, 2, launchAuthId, loginUser.getUid(), userInfoEntity.getCid(), null);
        BaseVo baseVo = new BaseVo();
        baseVo.setId(id);
        return ResponseResultUtil.success(baseVo);
    }

    private void updateMessageStatus(Long messageId, Integer accept) {
        if (null == messageId) {
            return;
        }
        MessageEntity messageEntity = messageMapper.selectById(messageId);
        if (null == messageEntity) {
            return;
        }
        String otherParams = messageEntity.getOtherParams();
        if (StringUtils.isEmpty(otherParams)) {
            return;
        }
        ShareMessageDto shareMessageDto = JSONObject.parseObject(otherParams, ShareMessageDto.class);
        shareMessageDto.setStatus(accept);

        MessageEntity updateEntity = new MessageEntity();
        updateEntity.setId(messageId);
        updateEntity.setOtherParams(JSONObject.toJSONString(shareMessageDto));
        messageMapper.updateById(updateEntity);
    }

    private boolean check(Long authId, Long launchAuthId, Integer type) {
        Long count = type.equals(0) ? followService.getByAuthId(authId, launchAuthId) : followService.getByAuthId(launchAuthId, authId);
        return count != null && count > 0;
    }

    @Override
    public ResponseResult invite(ShareDto share) {
        return add(share, 0);
    }

    private ResponseResult add(ShareDto share, Integer type) {
        AuthInfoVo authInfoEntity = (AuthInfoVo) StpUtil.getSession().get("loginInfo");
        if (null == authInfoEntity) {
            return ResponseResultUtil.authInfoFailure();
        }
        UserInfoVo loginVo = userInfoService.getByAuthId(authInfoEntity.getId());
        if (null == loginVo) {
            return ResponseResultUtil.authInfoFailure();
        }
        if (null == share) {
            return ResponseResultUtil.paramFailure();
        }
        String account = share.getAccount();
        if (StringUtils.isEmpty(account)) {
            return ResponseResultUtil.paramFailure();
        }
        String phone = null;
        Long uid = null;
        if (account.length() == 11) {
            phone = account;
        } else {
            uid = Long.valueOf(account);
        }
        boolean equals = type.equals(1);

        if (StringUtils.isEmpty(phone) && null == uid) {
            return ResponseResultUtil.paramFailure();
        }

        ShareEntity entity = new ShareEntity();
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        if (StringUtils.isNotEmpty(phone)) {
            if (checkRepeat(type, phone, null, authInfoEntity.getId())) {
                return ResponseResultUtil.failure(equals ? "请勿重复邀请" : "请勿重复申请", equals ? 11009 : 11010);
            }
            if (phone.equals(authInfoEntity.getUsername())) {
                return ResponseResultUtil.failure(equals ? "请勿邀请当前账号" : "请勿关注当前账号", equals ? 11007 : 11008);
            }
            entity.setPhone(phone);
            userInfoEntity = userInfoService.getByPhone(phone);
            if (null == userInfoEntity) {
                return ResponseResultUtil.failure("用户不存在", 11006);
            }
            entity.setUid(userInfoEntity.getId());
            if (check(authInfoEntity.getId(), userInfoEntity.getAuthId(), type)) {
                return ResponseResultUtil.failure(equals ? "邀请关注已同意" : "申请关注已同意", equals ? 11004 : 11005);
            }
        } else if (null != uid) {
            if (checkRepeat(type, null, uid, authInfoEntity.getId())) {
                return ResponseResultUtil.failure(equals ? "请勿重复邀请" : "请勿重复申请", equals ? 11009 : 11010);
            }
            entity.setUid(uid);
            userInfoEntity = userInfoService.getByUid(uid);
            if (null == userInfoEntity) {
                return ResponseResultUtil.failure("用户不存在", 11006);
            }
            if (uid.equals(loginVo.getUid())) {
                return ResponseResultUtil.failure(equals ? "请勿邀请当前账号" : "请勿关注当前账号", equals ? 11007 : 11008);
            }
            entity.setPhone(userInfoEntity.getPhone());
            if (check(authInfoEntity.getId(), userInfoEntity.getAuthId(), type)) {
                return ResponseResultUtil.failure(equals ? "邀请关注已同意" : "申请关注已同意", equals ? 11004 : 11005);
            }
        }


        String title = "";
        String content = "";
        String nickName = "";
        String avatarsUrl = "";
        if (equals) {
            nickName = StringUtils.isEmpty(loginVo.getNickName()) ? loginVo.getPhone() : loginVo.getNickName();
            //content = nickName + "邀请你关注他";
            content = InviteContentEnum.getByCode(share.getLanguage()).replace(LanguageEnum.NICKNAME.getValue(), nickName);
            title = "邀请关注";
            avatarsUrl = loginVo.getAvatarsUrl();
        } else {
            nickName = StringUtils.isEmpty(loginVo.getNickName()) ? loginVo.getPhone() : loginVo.getNickName();
            //content = nickName + "申请关注你";
            content = ApplyContentEnum.getByCode(share.getLanguage()).replace(LanguageEnum.NICKNAME.getValue(), nickName);
            title = "申请关注";
        }

        entity.setLaunchAuthId(authInfoEntity.getId());
        entity.setDataTypes(share.getDataTypes());
        entity.setIsRead(1);
        entity.setType(type);
        entity.setState(StatusEnum.VALID.getKey());
        entity.setCreateTime(DateUtil.now());
        shareMapper.insert(entity);

        ShareMessageDto dto = new ShareMessageDto();
        dto.setNickName(nickName);
        dto.setAvatarsUrl(avatarsUrl);
        dto.setStatus(0);
        dto.setShareId(entity.getId());
        sendMessage(title, content, JSONObject.toJSONString(dto), type, userInfoEntity.getAuthId(), loginVo.getUid(), userInfoEntity.getCid(), entity.getId());

        BaseVo baseVo = new BaseVo();
        baseVo.setId(entity.getId());
        return ResponseResultUtil.success(baseVo);
    }

    private boolean checkRepeat(Integer type, String phone, Long uid, Long launchAuthId) {
        LambdaQueryWrapper<ShareEntity> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ShareEntity::getState, StatusEnum.VALID.getKey());
        queryWrapper.isNull(ShareEntity::getAccept);
        queryWrapper.eq(ShareEntity::getType, type);
        queryWrapper.eq(StringUtils.isNotEmpty(phone), ShareEntity::getPhone, phone);
        queryWrapper.eq(null != uid, ShareEntity::getUid, uid);
        queryWrapper.eq(ShareEntity::getLaunchAuthId, launchAuthId);
        return shareMapper.selectCount(queryWrapper) > 0;
    }

    private void sendMessage(String title, String content, String param, Integer type, Long authId, Long uid, String cid, Long sid) {
        AppPushUtils.sendMessage(cid, "V Band", content);
        MessageEntity messageEntity = new MessageEntity();
        messageEntity.setTitle(title);
        messageEntity.setContent(content);
        messageEntity.setOtherParams(param);
        messageEntity.setType(type);
        messageEntity.setAuthId(authId);
        messageEntity.setUid(uid);
        messageEntity.setIsRead(1);
        messageEntity.setSid(sid);
        messageEntity.setState(StatusEnum.VALID.getKey());
        messageEntity.setCreateTime(DateUtil.nowSecond());
        messageMapper.insert(messageEntity);
    }


    @Override
    public ResponseResult apply(ShareDto share) {
        return add(share, 1);
    }

    @Override
    public ShareEntity getById(Long id) {
        if (null == id) {
            return null;
        }
        return shareMapper.selectById(id);
    }

    @Override
    public ResponseResult edit(ShareDto share) {
        if (null == share || null == share.getId()) {
            return ResponseResultUtil.paramFailure();
        }
        ShareEntity entity = new ShareEntity();
        entity.setId(share.getId());
        entity.setDataTypes(share.getDataTypes());
        shareMapper.updateById(entity);
        return ResponseResultUtil.success();
    }
}

